/*
 * Copyright 2003-2006 (c) Live Media Pty Ltd. <argot@einet.com.au> 
 *
 * This software is licensed under the Argot Public License 
 * which may be found in the file LICENSE distributed 
 * with this software.
 *
 * More information about this license can be found at
 * http://www.einet.com.au/License
 * 
 * The Developer of this software is Live Media Pty Ltd,
 * PO Box 4591, Melbourne 3001, Australia.  The license is subject 
 * to the law of Victoria, Australia, and subject to exclusive 
 * jurisdiction of the Victorian courts.
 */

%module(package = "meta/argot") meta

%{
	#include "meta/TypeMeta.h"
	#include "meta/MetaDefinition.h"
	#include "meta/MetaEncoding.h"
	#include "meta/MetaEnvelop.h"
	#include "meta/MetaIdentified.h"
	#include "meta/MetaMarshaller.h"
%}

%include "argot_exception.i"

// --- convenience macros -------

%define %meta_ignore(cname)
	//%ignore meta_##cname##_name;
%enddef

%define %add_metaname(cname)
/*	%immutable meta_##cname::name;

	%extend meta_##cname
	{
		static const type_name* name;
	}

%{	
	type_name* meta_##cname##_name_get(meta_##cname* self)
	{
		return &meta_##cname##_name;
	}	
%}*/
%enddef


%define %add_metamethods_without_do_0(cname)
%set_constructor_0(meta_##cname, meta_##cname##_init);
%add_metaname(cname)
%add_static_bound_method( meta_##cname, int, read, meta_##cname##_read, type_input_stream * in, type_element * element, void * data )
%add_static_bound_method( meta_##cname, int, write, meta_##cname##_write, type_output_stream * out, void * o, type_element * element, void * data )
%enddef

%define %add_metamethods_without_do_1(cname, type1, arg1)
%set_constructor_1(meta_##cname, meta_##cname##_init, type1, arg1);
%add_metaname(cname)
%add_static_bound_method( meta_##cname, int, read, meta_##cname##_read, type_input_stream * in, type_element * element, void * data )
%add_static_bound_method( meta_##cname, int, write, meta_##cname##_write, type_output_stream * out, void * o, type_element * element, void * data )
%enddef

%define %add_metamethods_without_do_2(cname, type1, arg1, type2, arg2)
%set_constructor_2(meta_##cname, meta_##cname##_init, type1, arg1, type2, arg2);
%add_metaname(cname)
%add_static_bound_method( meta_##cname, int, read, meta_##cname##_read, type_input_stream * in, type_element * element, void * data )
%add_static_bound_method( meta_##cname, int, write, meta_##cname##_write, type_output_stream * out, void * o, type_element * element, void * data )
%enddef

%define %add_metamethods_0(cname)
%add_metamethods_without_do_0(cname)
%add_static_bound_method( meta_##cname, int, do_read, meta_##cname##_do_read, type_input_stream * in, type_element * element, void * data )
%add_static_bound_method( meta_##cname, int, do_write, meta_##cname##_do_write, type_output_stream * out, void * o, type_element * element, void * data )
%enddef

%define %add_metamethods_1(cname, type1, arg1)
%add_metamethods_without_do_1(cname, type1, arg1)
%add_static_bound_method( meta_##cname, int, do_read, meta_##cname##_do_read, type_input_stream * in, type_element * element, void * data )
%add_static_bound_method( meta_##cname, int, do_write, meta_##cname##_do_write, type_output_stream * out, void * o, type_element * element, void * data )
%enddef

%define %add_metamethods_2(cname, type1, arg1, type2, arg2)
%add_metamethods_without_do_2(cname, type1, arg1, type2, arg2)
%add_static_bound_method( meta_##cname, int, do_read, meta_##cname##_do_read, type_input_stream * in, type_element * element, void * data )
%add_static_bound_method( meta_##cname, int, do_write, meta_##cname##_do_write, type_output_stream * out, void * o, type_element * element, void * data )
%enddef


%define %add_exc(cname, pyname)
	%exception cname##_read
	{
		ArgotConditionalExc( result == TYPE_EOF, SWIG_ValueError, "EOF encountered in " #pyname ".do_read" )
		ArgotConditionalExc( result != TYPE_OK, SWIG_ValueError, "Error occured in " #pyname ".do_read" )
	}
	%exception cname##_write
	{
		ArgotConditionalExc( result == TYPE_EOF, SWIG_ValueError, "EOF encountered in " #pyname ".do_write" )
		ArgotConditionalExc( result != TYPE_OK, SWIG_ValueError, "Error occured in " #pyname ".do_write" )
	}
	%exception cname##_do_read
	{
		ArgotConditionalExc( result == TYPE_EOF, SWIG_ValueError, "EOF encountered in " #pyname ".do_read" )
		ArgotConditionalExc( result != TYPE_OK, SWIG_ValueError, "Error occured in " #pyname ".do_read" )
	}
	%exception cname##_do_write
	{
		ArgotConditionalExc( result == TYPE_EOF, SWIG_ValueError, "EOF encountered in " #pyname ".do_write" )
		ArgotConditionalExc( result != TYPE_OK, SWIG_ValueError, "Error occured in " #pyname ".do_write" )
	}
%enddef

%define %rename_and_exc(cname, pyname)
	%fix_naming_to(cname, pyname);
	%add_exc(cname, pyname)
%enddef

// ------ end convenience macros ---------


%fix_naming_to(meta_expression, MetaExpression);
%meta_ignore(expression)
%include "meta/MetaExpression.h"
%set_constructor_2(meta_expression, meta_expression_init, typeReader, reader, typeWriter, writer);
%add_metaname(expression);


%rename_and_exc(meta_abstract, MetaAbstract);
%meta_ignore(abstract)
%include "meta/MetaAbstract.h"
%add_metamethods_0(abstract);
%add_bound_method(meta_abstract, void, add_map, meta_abstract_add_map, int concreteId, int mapId );
%add_bound_method(meta_abstract, int, is_mapped, meta_abstract_is_mapped, int id );
%add_static_bound_method(meta_abstract, void*, construct, meta_abstract_construct, type_library * library, void ** objects, int size );


%rename_and_exc(meta_array, MetaArray);
%meta_ignore(array)
%include "meta/MetaArray.h"
%add_metamethods_2(array, meta_expression *, size, meta_expression *, type);


%rename_and_exc(meta_basic, MetaBasic);
%meta_ignore(basic)
%include "meta/MetaBasic.h"
%add_metamethods_2(basic, int, width, int, flags);


%rename_and_exc(meta_map, MetaMap);
%ignore meta_map::abstract;
%ignore meta_map::concrete;
%meta_ignore(map)
%include "meta/MetaMap.h"
%add_metamethods_2(map, int, abstract, int, concrete);
%add_prop(meta_map, int, abstract_type, meta_map_get_abstract_type, meta_map_set_abstract_type);
%add_prop(meta_map, int, concrete_type, meta_map_get_concrete_type, meta_map_set_concrete_type);


%rename_and_exc(meta_name, MetaName);
%meta_ignore(name)
%include "meta/MetaName.h"
%ignore meta_name::xxx;
%inline
%{
	typedef struct meta_name
	{
		void* xxx;
	} meta_name;
	
	void meta_name_init(meta_name* name)
	{
	}
%}
%add_metamethods_without_do_0(name);


%rename_and_exc(meta_reference, MetaReference);
%meta_ignore(reference)
%include "meta/MetaReference.h"
%add_metamethods_2(reference, int, type, char *, desc);
%add_prop(meta_reference, int, type, meta_reference_get_type, meta_reference_set_type);
%add_readonly_prop(meta_reference, char*, description, meta_reference_get_description);

%rename_and_exc(meta_sequence, MetaSequence);
%meta_ignore(sequence)
%include "meta/MetaSequence.h"
%add_metamethods_2(sequence, meta_expression **, objects, int, size);
%add_static_bound_method(meta_sequence, void*, construct, meta_sequence_construct, type_list * objects, type_map * map, void * data);


%include "meta/MetaDefinition.h"

%rename_and_exc(meta_encoding, MetaEncoding);
%meta_ignore(encoding)
%include "meta/MetaEncoding.h"
%add_metamethods_2(encoding, meta_expression *, data, char *, type);

%rename_and_exc(meta_envelop, MetaEnvelop);
%meta_ignore(envelop)
%include "meta/MetaEnvelop.h"
%add_metamethods_2(envelop, meta_expression *, size, meta_expression *, type);

%rename_and_exc(meta_identified, MetaIdentified);
%meta_ignore(identified)
%include "meta/MetaIdentified.h"
%add_metaname(identified)

%add_static_bound_method( meta_identified, int, read, meta_identified_read, type_input_stream * in, type_element * element, void * data )
%add_static_bound_method( meta_identified, int, write, meta_identified_write, type_output_stream * out, void * o, type_element * element, void * data )
%add_static_bound_method( meta_identified, int, do_read, meta_identified_do_read, type_input_stream * in, type_element * element, void * data )
%add_static_bound_method( meta_identified, int, do_write, meta_identified_do_write, type_output_stream * out, void * o, void * data )

%add_static_bound_method(meta_identified, void*, construct, meta_identified_construct, type_list * list, type_map * map, void * data);

%add_exc(meta, MetaMarshaller)
%meta_ignore(marshaller)
%include "meta/MetaMarshaller.h"
